/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gps.decoder;

import pe.gps.record.Record;
import pe.gps.record.RecordAlarma;
import pe.gps.record.Record_EV603;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import pe.gps.log.Log;

/**
 *
 * @author romulogalindo
 */
public class Ev603 extends Decoder {

    private String type;
    private int flag;
    private String msg;

    public Ev603() {
        this.record = new Record_EV603();
    }

    @Override
    public void decode(ByteBuffer buffer) {
        try {
            state = 0;
            record.setType(state);
            buffer.flip();

            Charset charset = Charset.forName("ISO-8859-1");
            CharsetDecoder decoder = charset.newDecoder();
            CharBuffer charBuffer = decoder.decode(buffer);

            msg = charBuffer.toString();
            if (msg.contentEquals("")) {
                return;
            }
            Log.log("[Ev603]msg:[" + msg + "]", Log.DEBUG);
            String[] partes = msg.split(",");
            if (partes.length == 0) {
                return;
            }
            type = partes[0];
            switch (type) {
                case "!1":
                    //Imei
                    Log.log("[Ev603]Logueo]", Log.DEBUG);
                    imei = partes[1].replace(";", "");
                    record.setId(imei);
                    //esto es un logeo
                    state = 1;
                    record.setType(state);
                    break;
                case "!A":
                    //Gps data
                    Log.log("[Ev603]Data", Log.DEBUG);
                    if (record.getId().isEmpty()) {
                        throw new Exception("[Ev603]Dispositivo sin ID");
                    }
                    //fecha
                    String[] fechas = partes[1].split("/");
                    Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
                    time.clear();
                    time.set(Calendar.DAY_OF_MONTH, Integer.valueOf(fechas[0]));
                    time.set(Calendar.MONTH, Integer.valueOf(fechas[1]) - 1);
                    time.set(Calendar.YEAR, 2000 + Integer.valueOf(fechas[2]));
                    fechas = partes[2].split(":");
                    time.set(Calendar.HOUR, Integer.valueOf(fechas[0]));
                    time.set(Calendar.MINUTE, Integer.valueOf(fechas[1]));
                    time.set(Calendar.SECOND, Integer.valueOf(fechas[2]));
                    record.getPosicion().setFecha(time.getTime());
                    //latitud
                    if (!partes[3].isEmpty()) {
                        record.getPosicion().setLatitud(Double.valueOf(partes[3]));
                    }
                    //longitud
                    if (!partes[4].isEmpty()) {
                        record.getPosicion().setLongitud(Double.valueOf(partes[4]));
                    }
                    //velocidad
                    if (!partes[5].isEmpty()) {
                        record.getPosicion().setVelocidad(Double.valueOf(partes[5]).intValue());
                    }
                    //rumbo
                    if (!partes[6].isEmpty()) {
                        record.getPosicion().setDireccion(Double.valueOf(partes[6]).intValue());
                    }
                    //flag
                    if (!partes[7].isEmpty()) {
                        flag = Integer.valueOf(partes[7].replace(";", ""));
                    }
                    state = 2;
                    record.setType(state);
                    if (flag != 0) {
                        //hay una alarma
                        if (flag == 6) {
                            record.getEstado().setBatdis(Boolean.TRUE);
                        } else if (flag == 16) {
                            record.getEstado().setBatdis(Boolean.FALSE);
                        } else if (flag == 7) {
                            record.getEstado().setCarga_bateria(10);
                        } else {
                            System.out.println("Alarma desconocida: " + flag);
                        }
                    }
                    break;
                case "!5":
                    //Heartbeat
                    Log.log("[Ev603]HEartbeat", Log.DEBUG);
                    record.getEstado().setSenal_gsm(procesSenal(Integer.parseInt(partes[1]), 0, 31));
                    record.getEstado().setSenal_gps(partes[2].equals("A") ? 'A' : 'B');
                    state = 4;
                    record.setType(state);
                    break;
                case "!B":
                    Log.log("[Ev603]Data anterior", Log.DEBUG);
                    break;
                default:
                    Log.log("[Ev603]Comando desconocido: " + type, Log.DEBUG);
                    break;
            }
        } catch (Exception ex) {
//            Log.log("[GT06N]Error desencriptando: " + ex, Log.ERROR);
            ex.printStackTrace();
//            Log.log("[GT06N]Mensaje original: " + msg, Log.ERROR);
            state = 0;
            record.setType(state);
        }
    }

    private Character procesSenal(int posicion, int menor, int mayor) {
        int capacidad = mayor - menor;
        capacidad++;
        Map<Integer, Character> mapa = new HashMap<>();
        mapa.put(0, 'E');
        mapa.put(1, 'D');
        mapa.put(2, 'C');
        mapa.put(3, 'B');
        mapa.put(4, 'A');
        double n1 = (double) capacidad / (double) 4;
        int n2 = (int) Math.round((double) posicion / n1);
        return mapa.get(n2);
    }

    public String getType() {
        return type;
    }

    public int getFlag() {
        return flag;
    }

    @Override
    public ByteBuffer response() {
        if (state == 0) {
            return null;
        } else {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            buffer.put("ok".getBytes());
            buffer.flip();
            return buffer;
        }
    }

    @Override
    public String toString() {
        return "{ID=" + record.getId() + ",POSICION=" + record.getPosicion() + ",ESTADO=" + record.getEstado() + "}";
    }

    @Override
    public List<Record> decoder(ByteBuffer buffer) {
        decode(buffer);
        List<Record> records = new ArrayList<>();
        records.add(record);
        return records;
    }

    @Override
    public List<Record> decoderIMEI(ByteBuffer buffer) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}
